package com.thinkit.bigdata.web.controller.sercutiry;

import com.thinkit.bigdata.core.feature.orm.mybatis.Page;
import com.thinkit.bigdata.core.util.StringUtil;
import com.thinkit.bigdata.web.model.result.ConfigResult;
import com.thinkit.bigdata.web.model.result.Constants;
import com.thinkit.bigdata.web.model.sec.SysRole;
import com.thinkit.bigdata.web.model.sec.SysRoleExample;
import com.thinkit.bigdata.web.model.sec.User;
import com.thinkit.bigdata.web.service.sec.RoleService;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by lihongli on 2018/9/7
 */
@Controller
@RequestMapping("role")
public class RoleController {

    private static Logger logger = Logger.getLogger(RoleController.class);

    @Resource
    private RoleService roleService;

    /**
     * 请求进入角色管理页面
     *
     * @param request
     * @param model
     * @return
     */
    @RequestMapping("/roles")
    public String role(HttpServletRequest request, Model model) {
        logger.info("请求进入角色管理页面");
        return "SercutiryViews/role";
    }

    /**
     * 获取所有角色信息
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("/getAllRole")
    public List<SysRole> getAllRole(HttpServletRequest request) {
        logger.info("获取所有角色信息");
        SysRoleExample example = new SysRoleExample();
        // 只检索出启用状态的角色信息
        example.createCriteria().andStatusEqualTo(1);
        example.setOrderByClause("name asc");
        return roleService.selectByExample(example);
    }

    /**
     * 获取所有不大于自己角色级别的角色信息
     * 用于用户管理界面，新增修改
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("/getAllRoleByUser")
    public List<SysRole> getAllRoleByUser(HttpServletRequest request) {
        logger.info("获取所有不大于自己角色的角色信息");
        SysRoleExample example = new SysRoleExample();
        // 只检索出启用状态的角色信息
        example.createCriteria().andStatusEqualTo(1);
        example.setOrderByClause("name asc");
        //获取角色当前标识
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        List<SysRole> sysRoles=new ArrayList<>();
        if(user.getRolelist().size()==0){//超管
            return roleService.selectByExample(example);
        }
        for (SysRole sysRole:user.getRolelist()) {
            if (sysRole.getCode().lastIndexOf("_") != -1) {//若包含上下级关系
                for (SysRole role : roleService.selectByExample(example)) {
                    if (role.getCode().indexOf(sysRole.getCode()) == 0&&!roleService.RoleEquals(sysRoles,role)){
                        sysRoles.add(role);
                    }
                }
            }else{//含有最高级角色直接返回所有角色
                return roleService.selectByExample(example);
            }
        }
        return sysRoles;
    }



    /**
     * 分页查询角色信息
     *
     * @param request
     * @param status
     * @param sortOrder
     * @param sortName
     * @param pageNum
     * @param pageSize
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/rolesByPage", method = RequestMethod.POST)
    public Page<SysRole> rolesByPage(
            HttpServletRequest request,
            @RequestParam(value = "status", required = false) List<Integer> status,
            @RequestParam(value = "sortOrder") String sortOrder,
            @RequestParam(value = "sortName") String sortName,
            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        // 查询参数 角色标识名称
        String name = request.getParameter("name");
        String code = request.getParameter("code");
        String logTxt = "【角色管理分页查询】";
        logger.info(logTxt + "查询条件: pageNum=" + pageNum);
        logger.info(logTxt + "查询条件: pageSize=" + pageSize);
        logger.info(logTxt + "查询条件: name=" + name);
        // 查询条件设置
        SysRoleExample example = new SysRoleExample();
        SysRoleExample.Criteria criteria = example.createCriteria();
        if (StringUtil.isNotEmpty(code)) {
            criteria.andCodeLike("%" + code + "%");
        }
        if (StringUtil.isNotEmpty(name)) {
            criteria.andNameLike("%" + name + "%");
        }
        if (status != null && !status.isEmpty()) {
            criteria.andStatusIn(status);
        }
        // 排序方式设置
        example.setOrderByClause(sortName + " " + sortOrder);
        // 分页信息设置
        Page<SysRole> page = new Page<>(pageNum, pageSize);
        roleService.selectByExample(page, example);
        logger.info(logTxt + "查询完成，共计查询到" + page.getResult().size() + "条角色信息");
        return page;
    }

    /**
     * code唯一性检查
     *
     * @param request
     * @param code
     * @return
     */
    @ResponseBody
    @RequestMapping("/codeUniqueCheck")
    public ConfigResult codeUniqueCheck(HttpServletRequest request, String code) {
        String logTxt = "【code唯一性检查】";
        logger.info(logTxt + "code=" + code);
        SysRoleExample example = new SysRoleExample();
        example.createCriteria().andCodeEqualTo(code);
        Integer count = roleService.countRole(example);
        if (count > 0) {
            logger.info(logTxt + code + "已存在");
            return new ConfigResult(Constants.ERROR, "此编码已存在");
        } else {
            logger.info(logTxt + code + "校验通过");
            return new ConfigResult(Constants.SUCCESS, "√");
        }
    }

    /**
     * name唯一性检查
     *
     * @param request
     * @param name
     * @return
     */
    @ResponseBody
    @RequestMapping("/nameUniqueCheck")
    public ConfigResult nameUniqueCheck(HttpServletRequest request, String name) {
        String logTxt = "【name唯一性检查】";
        logger.info(logTxt + "name=" + name);
        SysRoleExample example = new SysRoleExample();
        example.createCriteria().andNameEqualTo(name);
        Integer count = roleService.countRole(example);
        if (count > 0) {
            logger.info(logTxt + name + "已存在");
            return new ConfigResult(Constants.ERROR, "此名称已存在");
        } else {
            logger.info(logTxt + name + "校验通过");
            return new ConfigResult(Constants.SUCCESS, "√");
        }
    }

    @ResponseBody
    @RequestMapping(value = "/parentRoleAll", method = RequestMethod.GET)
    public List<SysRole> parentRoleAll(HttpServletRequest request) {
        //获取角色当前标识
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        boolean newCode=true;
        SysRoleExample example = new SysRoleExample();
        example.createCriteria().andParentroleidIsNull();
        example.setOrderByClause("id asc");
        List<SysRole> sysRoles=new ArrayList<>();
        if (user.getUsername().equals("admin")){
            return roleService.selectByExample(example);
        }
        for (SysRole sysRole:user.getRolelist()) {
            int lastIndex=sysRole.getCode().lastIndexOf("_")+1;
            if (lastIndex != 0) {//若包含上下级关系
                String str=sysRole.getCode().substring(0,lastIndex);
                for (SysRole role : roleService.selectByExample(example)) {
                    //获取级别小于等于自己的/或等于自己级别的兄弟节点
                    if (role.getCode().length()==sysRole.getCode().length()&&role.getCode().indexOf(str) == 0&&!roleService.RoleEquals(sysRoles,role)){
                            sysRoles.add(role);
                    }else if (role.getCode().indexOf(sysRole.getCode()) == 0&&!roleService.RoleEquals(sysRoles,role)){
                        sysRoles.add(role);
                    }
                }
            }else{//不包含或为最高级
                newCode=false;
                break;
            }
        }
        return newCode?sysRoles:roleService.selectByExample(example);
    }

    /**
     * 角色新增
     *
     * @param role
     * @return
     */
    @ResponseBody
    @RequestMapping("/roleAdd")
    public ConfigResult roleAdd(HttpServletRequest request, SysRole role) {
        String logTxt = "【角色新增】";
        logger.info(logTxt + role.toString());
        // 获取当前用户信息
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        boolean flag=false;
        if (user.getUsername().equals("admin")){
            flag=true;
        }else{
            for (SysRole userRole:user.getRolelist()){
                if(userRole.getCode().indexOf("_")==-1){
                    flag=true;
                    break;
                }
            }
        }
        if(!flag){
            for (SysRole userRole:user.getRolelist()){
                int lastIndex=userRole.getCode().lastIndexOf("_")+1;
                String str=userRole.getCode().substring(0,lastIndex);
                if(role.getCode().indexOf(userRole.getCode())==0){
                    flag=true;
                    break;
                }else if(role.getCode().length()==userRole.getCode().length()&&role.getCode().indexOf(str) == 0){//操作兄弟节点
                    flag=true;
                    break;
                }
            }
        }
        if (!flag){
            logger.info(logTxt + "您无权新增该角色");
            return new ConfigResult(Constants.FAIL, "您无权新增该角色");
        }
        Date date = new Date();
        // 设置创建人信息
        role.setCreatetime(date);
        role.setCreateuserid(user.getId());
        role.setLastupdatetime(date);
        role.setLastupdateuserid(user.getId());
        try {
            Integer rowNum = roleService.insert(role);
            if (rowNum > 0) {
                logger.info(logTxt + "角色添加成功");
                return new ConfigResult(Constants.SUCCESS, "角色添加成功");
            } else {
                logger.info(logTxt + "角色添加失败");
                return new ConfigResult(Constants.FAIL, "角色添加失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + "角色添加出现错误", e);
            return new ConfigResult(Constants.ERROR, "角色添加出现错误");
        }
    }

    /**
     * 根据主键获取角色信息
     *
     * @param request
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping("/roleGetByPK")
    public SysRole roleGetByPK(HttpServletRequest request, @RequestParam("id") Long id) {
        logger.info("获取id为" + id + "的角色信息");
        return roleService.selectRoleByPK(id);
    }

    /**
     * 角色修改
     *
     * @param request
     * @param role
     * @return
     */
    @ResponseBody
    @RequestMapping("/roleUpdate")
    public ConfigResult roleUpdate(HttpServletRequest request, SysRole role) {
        String logTxt = "【角色修改】";
        logger.info(logTxt + role.toString());
        // 获取当前用户信息
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        //判断角色级别开始
        boolean flag=false;
        if (user.getUsername().equals("admin")){
            flag=true;
        }else{
            for (SysRole userRole:user.getRolelist()){
                if(userRole.getCode().indexOf("_")==-1){
                    flag=true;
                    break;
                }
            }
        }
        if(!flag){
            for (SysRole userRole:user.getRolelist()){
                int lastIndex=userRole.getCode().lastIndexOf("_")+1;
                String str=userRole.getCode().substring(0,lastIndex);
                if(role.getCode().indexOf(userRole.getCode())==0){
                    flag=true;
                    break;
                }else if(role.getCode().length()==userRole.getCode().length()&&role.getCode().indexOf(str) == 0){//操作兄弟节点
                    flag=true;
                    break;
                }
            }
        }
        if (!flag){
            logger.info(logTxt + "您无权修改该角色");
            return new ConfigResult(Constants.FAIL, "您无权修改该角色");
        }
        // 设置修改人信息
        role.setLastupdatetime(new Date());
        role.setLastupdateuserid(user.getId());
        try {
            Integer rowNum = roleService.update(role);
            if (rowNum > 0) {
                logger.info(logTxt + "角色修改成功");
                return new ConfigResult(Constants.SUCCESS, "角色修改成功");
            } else {
                logger.info(logTxt + "角色修改失败");
                return new ConfigResult(Constants.FAIL, "角色修改失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + "角色修改出现错误", e);
            return new ConfigResult(Constants.ERROR, "角色修改出现错误");
        }
    }

    /**
     * 单个role状态修改
     *
     * @param request
     * @param id
     * @param status
     * @return
     */
    @ResponseBody
    @RequestMapping("/roleStatusSingle")
    public ConfigResult roleStatusSingle(HttpServletRequest request, @RequestParam("id") Long id, @RequestParam("status") Integer status) {
        // 操作类型
        String opType = Constants.getStatusName(status);
        String logTxt = "【角色状态" + opType + "】";
        logger.info(logTxt + "修改id为" + id + "的角色状态");
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        // 值设置
        SysRole role = new SysRole();
        role.setId(id);
        role.setStatus(status);
        role.setLastupdatetime(new Date());
        role.setLastupdateuserid(user.getId());
        try {
            Integer rowNum = roleService.update(role);
            if (rowNum > 0) {
                logger.info(logTxt + "成功修改id为" + id + "的角色状态");
                return new ConfigResult(Constants.SUCCESS, "角色状态修改成功");
            } else {
                logger.info(logTxt + "角色状态修改失败");
                return new ConfigResult(Constants.FAIL, "角色状态修改失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + "角色状态修改出现错误", e);
            return new ConfigResult(Constants.ERROR, "角色状态修改出现错误");
        }
    }

    /**
     * 多个role状态修改
     *
     * @param request
     * @param idList
     * @param status
     * @return
     */
    @ResponseBody
    @RequestMapping("/roleStatusBatch")
    public ConfigResult roleStatusBatch(HttpServletRequest request, @RequestParam("idList") List<Long> idList, @RequestParam("status") Integer status) {
        // 操作类型
        String opType = Constants.getStatusName(status);
        String logTxt = "【角色状态批量" + opType + "】";
        logger.info(logTxt + "批量修改" + idList.size() + "个角色的状态");
        // 设置查询条件
        SysRoleExample example = new SysRoleExample();
        example.createCriteria().andIdIn(idList);
        // 值设置
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.SESSION_USER_INFO);
        SysRole role = new SysRole();
        role.setStatus(status);
        role.setLastupdatetime(new Date());
        role.setLastupdateuserid(user.getId());
        try {
            Integer rowNum = roleService.updateStatusBatch(role, example);
            if (rowNum > 0) {
                logger.info(logTxt + "角色状态批量修改成功");
                return new ConfigResult(Constants.SUCCESS, "角色状态批量修改成功");
            } else {
                logger.info(logTxt + "角色状态批量修改失败");
                return new ConfigResult(Constants.FAIL, "角色状态批量修改失败");
            }
        } catch (Exception e) {
            logger.error(logTxt + "角色状态批量修改出现错误", e);
            return new ConfigResult(Constants.ERROR, "角色状态批量修改出现错误");
        }
    }
    /**
     * 检查角色是否包含子角色
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/checkRoleHavChild", method = RequestMethod.GET)
    public ConfigResult checkRoleHavChild(@RequestParam("idList") List<Long> idList){
        if(roleService.checkRoleHavChild(idList)==0){
            return new ConfigResult(Constants.FAIL, "子角色使用中，不能删除父角色");
        }else if (roleService.checkRoleHavChild(idList)==1){
            return new ConfigResult(Constants.WARNING, "父角色下包含子角色，但是未使用");
        }
        return new ConfigResult(Constants.SUCCESS, "角色下无子角色");
    }
    /**
     * 检查角色是否在使用
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/checkRoleIsUsing", method = RequestMethod.GET)
    public ConfigResult checkRoleIsUsing(@RequestParam("idList") List<Long> idList){
        if(roleService.checkRoleIsUsing(idList)){
            return new ConfigResult(Constants.FAIL, "角色在使用中");
        }
        return new ConfigResult(Constants.SUCCESS, "角色没有被使用");
    }

    /**
     * 角色批量删除
     *
     * @param idList
     * @return
     */
    @ResponseBody
    @RequestMapping("/roleDeleteBatch")
    public ConfigResult roleDeleteBatch(@RequestParam("idList") List<Long> idList) {
        String logTxt = "【角色批量删除】";
        logger.info(logTxt + "批量删除" + idList.size() + "个角色");
        if (!idList.isEmpty()) {
            try {
                Integer rowNum = roleService.deleteRoleBatch(idList);
                if (rowNum > 0) {
                    logger.info(logTxt + "批量删除角色成功");
                    return new ConfigResult(Constants.SUCCESS, "角色批量删除成功");
                } else if(rowNum == -1){
                    logger.info(logTxt + "选中的角色或子角色正在使用，不可删除");
                    return new ConfigResult(Constants.FAIL, "选中的角色或子角色正在使用，不可删除");
                } else{
                    logger.info(logTxt + "角色批量删除失败");
                    return new ConfigResult(Constants.FAIL, "角色批量删除失败");
                }
            } catch (Exception e) {
                logger.error(logTxt + "角色批量删除出现错误", e);
                return new ConfigResult(Constants.ERROR, "角色批量删除出现错误");
            }
        } else {
            logger.info("未选择要删除的角色");
            return new ConfigResult(Constants.WARNING, "未选择要删除的角色");
        }
    }
}
